#ifndef FACILITYDEFINE_H
#define FACILITYDEFINE_H

#ifndef HEAD_Q_H
#include "../head_Q.h"
#endif

#ifndef GATE_H
#include "../Grid/Gate.h"
#endif

/**********************************
 * @brief 设施方向的枚举
 *
 * *******************************/
enum FacilityDirection
{
    Facility_UP,
    Facility_RIGHT,
    Facility_DOWN,
    Facility_LEFT,
};

/**********************************
 * @brief 设施类型的枚举
 *
 * *******************************/
enum class FacilityType
{
    Facility_NONE,   // 无
    HUB,             // 交付中心
    BELT,            // 传动带
    MINER,           // 开采器
    CUTTER,          // 裁剪器
    TRASH,           // 垃圾桶
    BALANCER,        // 分流器 new!
    PAINTER,         // 染色器 new!
    MIXER,           // 混色器 new!
    ROTATER,         // 旋转器 new!
    STACKER,         // 堆叠器 new!
};

/**********************************
 * @brief 设施类型的定义
 *
 * *******************************/
class FacilityDefine
{
protected:
    const static int max_interval = BOX_LENTH;// 最大的间隔
    inline static int speedToInterval(double process_speed){
        if(process_speed <= 0.0){return -1;}
        return (max_interval / process_speed);
    }// 速度转时间

    FacilityType facility_type;     // 类型
    int group_idx;                  // 组内序号 默认0
    std::string hash_id;            // hashid
    double process_speed;           // 处理速度
    int interval;                   // 处理间隔, 永远应该等于 speedToInterval(process_speed);
    int width, height;              // 高度 和 宽度
    int enters_num, exits_num;     // 入口数，出口数
    std::vector<EnterGate> relative_enters;
    std::vector<ExitGate> relative_exits;// 入口、出口相对位置 以设施的左上角为原点

public:
    FacilityDefine(
        FacilityType f_type,
        double process_speed,
        int width,
        int height,
        int enters_num,
        int exists_num,
        int group_idx = 0
    );
    // 从 类型 和 组内号 到 标识号
    inline static std::string fromTypeAndIdxToString(FacilityType f_type, int groupIdx){
        std::string res;
        switch(f_type){
        case FacilityType::HUB:
            res = "HUB_";
            break;
        case FacilityType::BELT:
            res = "BELT_";
            break;
        case FacilityType::CUTTER:
            res = "CUTTER_";
            break;
        case FacilityType::MINER:
            res = "MINER_";
            break;
        case FacilityType::TRASH:
            res = "TRASH_";
            break;
        case FacilityType::BALANCER:
            res = "BALANCER_";
            break;
        case FacilityType::PAINTER:
            res = "PAINTER_";
            break;
        case FacilityType::MIXER:
            res = "MIXER_";
            break;
        case FacilityType::ROTATER:
            res = "ROTATER_";
            break;
        case FacilityType::STACKER:
            res = "STACKER_";
            break;
        default:
            std::clog << ("others are not available!\n");
        }
        res += std::to_string(groupIdx);
        return res;
    }
    inline std::string get_Hashid(){return hash_id;}
    inline int getGroupIdx(){return group_idx;}
    inline FacilityType getFacilityType(){return facility_type;}
    friend class Facility;
    friend class Facility_Manager;
    friend class Base_Belt;
};

#endif // FACILITYDEFINE_H
